/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkWsFlvPlayer.h"
#include "MkUtil/MkLog.h"

CMkWsFlvPlayer::CMkWsFlvPlayer(CMkEvent *pEvent, CMkTimer* pTimer,const MkEventRemovedCallback& RemovedCb)
    : CMkHttpClient(pEvent, pTimer, RemovedCb)
    , CMkMediaSource(MkMediaSourceFlvPlayer)
    , m_nMaxLen(Len1M)
    , m_nOffset(0)
{
    m_pBuf = (Uint8*)malloc(m_nMaxLen);
}

Uint32 CMkWsFlvPlayer::StartMediaSource(const MkString& Url,const MkSourceResultCallback& ResultCb, const MkEsPacketCallback& EsCb/* = nullptr*/)
{
    CMkMediaSource::StartMediaSource(ResultCb, EsCb);
    return WebSocketConnect(Url, [this]() {
        if (m_ResultCb) {
            m_ResultCb(this, NoneError);
        }
    }, [this](const Uint8* pBuf, Uint32 nLen) {
        OnFlvData(pBuf, nLen);
    }, [this]() {
    });
}

Uint32 CMkWsFlvPlayer::OnFlvData(const Uint8* pBuf, Uint32 nLen)
{
    if (m_nOffset + nLen > m_nMaxLen) {
        MkErrorLog("recv max than %d not parsed\n", m_nMaxLen);
        Close();
        return NoneError;
    }
    memcpy(m_pBuf + m_nOffset, pBuf, nLen);
    m_nOffset += nLen;
    Uint32 nUsed = 0;
    Uint32 ErrorCode = m_FlvDemuxer.InputData(m_pBuf, m_nOffset, nUsed);
    MkCheckErrorLog(ErrorCode, "input data failed\n");
    if ((MkCodecUnknown != m_FlvDemuxer.GetVideoParam().GetCodec() || MkCodecUnknown != m_FlvDemuxer.GetAudioParam().GetCodec())
       && MkCodecUnknown == GetVideoParam().GetCodec() 
        && MkCodecUnknown == GetAudioParam().GetCodec()) {
        SetVideoParam(m_FlvDemuxer.GetVideoParam());
        SetAudioParam(m_FlvDemuxer.GetAudioParam());
        m_Duration = m_FlvDemuxer.GetDuration();
        m_FileSize = m_FlvDemuxer.GetFileSize();
    }
    MkEsPacket EsPacket;
    while (NoneError == m_FlvDemuxer.GetEsPacket(EsPacket)) {
        OnReadEsPacket(EsPacket);
    }

    memmove(m_pBuf, m_pBuf + nUsed, m_nOffset - nUsed);
    m_nOffset -= nUsed;
    return NoneError;
}

Uint32 CMkWsFlvPlayer::StopMediaSource()
{
    return Close();
}

CMkWsFlvPlayer::~CMkWsFlvPlayer()
{
    StopMediaSource();
    MkFree(m_pBuf);
}